package com.yanqu.road.logic.cross;

import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.rank.cross.CrossUserRank;
import com.yanqu.road.logic.bussiness.rank.RankBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.RankListHelper;
import com.yanqu.road.logic.pb.CrossRankPb;
import com.yanqu.road.logic.sort.CrossRankSort;
import com.yanqu.road.pb.rank.RankProto;

import java.math.BigInteger;
import java.util.*;

public class CrossActivityRankListModel {

    private int rankNum = GameConfig.RANK_DEFAULT_MAX_COUNT;

    private Comparator crossRankSort;

    private boolean isNeedSync = false;

    private boolean isUpdate = false;

    private boolean needUpdateDB;           //是否需要把数据入库

    private LinkedList<CrossUserRank> rankList;

    private int activityId;

    private int conditionType;

    private int rankCapacity = calcRankCapacity(GameConfig.RANK_DEFAULT_MAX_COUNT);

    public CrossActivityRankListModel(int activityId, boolean needUpdateDB) {
        crossRankSort = new CrossRankSort();
        rankList = new LinkedList<>();
        this.needUpdateDB = needUpdateDB;
        this.activityId = activityId;
    }

    public CrossActivityRankListModel(int activityId, boolean needUpdateDB, Comparator comparator) {
        crossRankSort = comparator;
        rankList = new LinkedList<>();
        this.needUpdateDB = needUpdateDB;
        this.activityId = activityId;
    }

    public int getActivityId() {
        return activityId;
    }

    public int getConditionType() {
        return conditionType;
    }

    public void setConditionType(int conditionType) {
        this.conditionType = conditionType;
    }

    public boolean isNeedSync() {
        return isNeedSync;
    }

    public void setNeedSync(boolean needSync) {
        isNeedSync = needSync;
    }

    public RankProto.RankListMsg.Builder getRankListMsg() {
        return initRankMsg();
    }

    public LinkedList<CrossUserRank> getRankList() {
        LinkedList<CrossUserRank> tempList = new LinkedList<>();
        for (CrossUserRank rank : new ArrayList<>(rankList)) {
            tempList.add(rank);
            if (tempList.size() >= rankNum) {
                break;
            }
        }
        return tempList;
    }

    public void setRankList(LinkedList<CrossUserRank> userRankList) {
        synchronized (this) {
            rankList = new LinkedList<>(userRankList);
            RankListHelper.checkUserRankListValid(rankList);       //校验一下数组
            rankList.sort(crossRankSort);
            while (rankList.size() > rankCapacity){
                rankList.removeLast();
            }
        }
    }

    private RankProto.RankListMsg.Builder initRankMsg() {
        List<CrossUserRank> crossUserRanks = null;
        synchronized (rankList) {
            crossUserRanks = new ArrayList<>(rankList);
        }
        return CrossRankPb.parseRankListMsg(crossUserRanks, rankNum);
    }

    public int getMyRank(long userId, long serverId) {
        int rank = -1;
        int index = 0;
        synchronized (this) {
            for(CrossUserRank userRank : rankList){
                if(userRank.getUserId() == userId && userRank.getUserBaseInfo().getServerId() == serverId){
                    if(userRank.getBigRankType() == eGamePlayerEventType.CatActivityDamageRank.getValue() && userRank.getValue().compareTo(BigInteger.ZERO) == 0){
                        rank = -1;
                    }else {
                        rank = index + 1;
                    }
                    break;
                }
                index++;
            }
        }
        if(rank > rankNum){
            rank = -1;
        }
        return rank;
    }

    //象棋需要临时排名返回排名变化
    public int getOtherRank(long userId, long serverId,LinkedList<CrossUserRank> otherRankList) {
        int rank = -1;
        int index = 0;
        synchronized (this) {
            for(CrossUserRank userRank : otherRankList){
                if(userRank.getUserId() == userId){
                    rank = index + 1;
                    break;
                }
                index++;
            }
        }
        if(rank > rankNum){
            rank = -1;
        }
        return rank;
    }

    public CrossUserRank getMyRankInfo(long userId, long serverId) {
        synchronized (this) {
            for(CrossUserRank userRank : rankList){
                if(userRank.getUserId() == userId && userRank.getUserBaseInfo().getServerId() == serverId){
                    return userRank;
                }
            }
        }
        return null;
    }

    public CrossUserRank getOtherRankInfo(long userId, long serverId,LinkedList<CrossUserRank> otherRankList) {
        synchronized (this) {
            for(CrossUserRank userRank : otherRankList){
                if(userRank.getUserId() == userId && userRank.getUserBaseInfo().getServerId() == serverId){
                    return userRank;
                }
            }
        }
        return null;
    }

    public RankProto.RankTempMsg.Builder getTopRankMsg() {
        synchronized (this) {
            for(CrossUserRank userRank : rankList){
                return CrossRankPb.parseRankTempMsg(userRank)                            ;
            }
        }
        return null;
    }

    /**
     * 添加到排行
     */
    public void rankChange(CrossUserRank crossUserRank) {
        boolean isChange = false;
        synchronized (this) {
            int size = rankList.size();
            CrossUserRank userRank = getMyRankInfo(crossUserRank.getUserId(), crossUserRank.getUserBaseInfo().getServerId());
            if(null != userRank){
                userRank.setUserBaseInfo(crossUserRank.getUserBaseInfo());
                if(0 != userRank.getValue().compareTo(crossUserRank.getValue()) || !userRank.getParam().equals(crossUserRank.getParam())){
                    userRank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                }
                userRank.setValue(crossUserRank.getValue());
                userRank.setParam(crossUserRank.getParam());
                isChange = true;
            }else {
                if (size < rankCapacity) {
                    CrossUserRank rank = crossUserRank.clone();
                    rank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                    rankList.add(rank);
                    isChange = true;
                } else if (crossRankSort.compare(crossUserRank, rankList.getLast()) < 0) {
                    CrossUserRank rank = crossUserRank.clone();
                    rank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                    rankList.removeLast();
                    rankList.add(rank);
                    isChange = true;
                }
            }
            if(isChange) {
                rankList.sort(crossRankSort);
                isNeedSync = true;
                isUpdate = true;
            }
        }
    }

    /**
     * 名次的变化，象棋大逃杀每场结束要名次的变化(通用的，以后有什么名次变化的都用这个)
     * @param otherUserRank
     * @param otherRankList
     */
    public void otherRankChange(CrossUserRank otherUserRank,LinkedList<CrossUserRank> otherRankList) {
        boolean isChange = false;
        int size = otherRankList.size();
        CrossUserRank userRank = getOtherRankInfo(otherUserRank.getUserId(), otherUserRank.getUserBaseInfo().getServerId(),otherRankList);
        if(null != userRank){
            CrossUserRank rank = otherUserRank.clone();
            if(0 != userRank.getValue().compareTo(otherUserRank.getValue())){
                rank.setLastUpdateTime(System.currentTimeMillis() / 1000);
            }
            rank.setValue(otherUserRank.getValue());
            rank.setParam(otherUserRank.getParam());
            otherRankList.remove(userRank);
            otherRankList.add(rank);
            isChange = true;
        }else {
            if (size < rankCapacity) {
                CrossUserRank rank = otherUserRank.clone();
                rank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                otherRankList.add(rank);
                isChange = true;
            } else if (crossRankSort.compare(otherUserRank, otherRankList.getLast()) < 0) {
                CrossUserRank rank = otherUserRank.clone();
                rank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                otherRankList.removeLast();
                otherRankList.add(rank);
                isChange = true;
            }
        }
        if(isChange) {
            otherRankList.sort(crossRankSort);
        }
    }

    public BigInteger getMinRankScore() {
        synchronized (this) {
            if (rankList.size() > 0 && rankList.size() >= rankNum) {
                return rankList.getLast().getValue();
            }
            return BigInteger.ZERO;
        }
    }

    public void setRankNum(int rankNum) {
        this.rankNum = rankNum;
        rankCapacity = calcRankCapacity(rankNum);
    }

    private int calcRankCapacity(int rankNum) {
        int value = rankNum / 2 + rankNum;
        if (value <= 200) {
            return 200;
        }
        return value;
    }

    /**
     * 跨服商战活动榜单保存
     */
    public void saveCrossTradeWarRankList() {
        if(needUpdateDB) {
            LinkedList<CrossUserRank> newRankList;
            synchronized (this) {
                if (!isUpdate) {
                    return;
                }
                newRankList = new LinkedList<>(rankList);
                isUpdate = false;
            }
            RankBussiness.updateCrossTradeWarRankList(newRankList);
        }
    }

    /**
     * 跨服活动榜单保存
     */
    public void saveCrossActivityRankList() {
        if(needUpdateDB) {
            LinkedList<CrossUserRank> newRankList;
            synchronized (this) {
                if (!isUpdate) {
                    return;
                }
                newRankList = new LinkedList<>(rankList);
                isUpdate = false;
            }
            RankBussiness.updateCrossActivityUserRankList(newRankList);
        }
    }

    /**
     * 跨服活动榜单保存
     */
    public void saveNewCrossActivityRankList() {
        if(needUpdateDB) {
            LinkedList<CrossUserRank> newRankList;
            synchronized (this) {
                if (!isUpdate) {
                    return;
                }
                newRankList = new LinkedList<>(rankList);
                isUpdate = false;
            }
            RankBussiness.updateCrossActivityNewRankList(newRankList, conditionType);
        }
    }

    public void saveCrossOreWarRankList() {
        if(needUpdateDB) {
            LinkedList<CrossUserRank> newRankList;
            synchronized (this) {
                if (!isUpdate) {
                    return;
                }
                newRankList = new LinkedList<>(rankList);
                isUpdate = false;
            }
            RankBussiness.updateCrossOreWarRankList(newRankList);
        }
    }

    //通用常驻内存活动
    public void saveCrossRelationRankList() {
        if(needUpdateDB) {
            LinkedList<CrossUserRank> newRankList;
            synchronized (this) {
                if (!isUpdate) {
                    return;
                }
                newRankList = new LinkedList<>(rankList);
                isUpdate = false;
            }
            RankBussiness.updateCrossRelationRankList(newRankList);
        }
    }

    public boolean isUpdate() {
        return isUpdate;
    }

    public void setUpdate(boolean update) {
        isUpdate = update;
    }

    /**
     * 获取LinkedList中指定索引附近一定数量的元素列表。
     * @param rank 排名
     * @param num 每边需要获取的元素数量
     * @return 包含指定索引附近元素的新LinkedList
     */
    public LinkedList<CrossUserRank> getSubList(int rank, int num) {
        int index = rank - 1;
        LinkedList<CrossUserRank> list = this.rankList;

        // 计算有效的开始和结束索引，确保不会越界
        int startIndex = Math.max(0, index - num);
        int endIndex = Math.min(list.size(), index + num + 1); // +1是因为endIndex是不包含的

        // 遍历并添加元素到subList
        LinkedList<CrossUserRank> subList = new LinkedList<>();
        for (int i = startIndex; i < endIndex; i++) {
            subList.add(list.get(i));
        }
        return subList;
    }

    /**
     * 获取LinkedList中指定排名前后指定数量的元素列表，不包括指定排名的元素。
     * @param rank 排名位置（以1为起始）
     * @param start 前面需要获取的元素数量
     * @param end 后面需要获取的元素数量
     * @return 包含指定排名前后元素的LinkedList，不包括指定排名的元素
     */
    public LinkedList<CrossUserRank> getSubListWithoutIndex(int rank, int start, int end) {
        LinkedList<CrossUserRank> list = this.rankList;
        // 计算有效的开始和结束索引，确保不会越界
        int index = rank - 1; // 将排名转换为列表索引
        int startIndex = Math.max(0, index - start - 1); // -1 是因为不包含index
        int endIndex = Math.min(list.size(), index + end); // 不包含index
        // 创建子列表，先添加前面的元素
        LinkedList<CrossUserRank> subList = new LinkedList<>();
        for (int i = startIndex; i < index; i++) {
            subList.addLast(list.get(i));
        }
        // 再添加后面的元素
        for (int i = index + 1; i < endIndex; i++) {
            subList.addLast(list.get(i));
        }
        return subList;
    }
}
